electronic.alchemy :: poste.io setup
electronic.alchemy
where the past meets the future
smartos > poste.io setup

poste.io setup

Created by hww3. Last updated by hww3, 5 years ago. Version #5.

Note: This document describes the process I used to set up poste.io in an LX zone on SmartOS. It may also be used as a guide to the steps needed for converting other docker images to run as LX zones with appropriate customization.

Assuming you have imgadm set up to import from the docker hub. Instructions for doing this can be found online.
imgadm import analogic/poste.io	

Note the uuid of the image (it will be on the first line)

Create a vmadm json file:

{
    "brand": "lx",
    "kernel_version": "3.13.0",
    "autoboot": false,
    "delegate_dataset": true,
"docker": "true", "image_uuid": "2a9c872d-b36d-2c84-aa80-37250b541164",
"alias": "smtp", "hostname": "smtp", "max_physical_memory": 2048, "quota": 20, "cpu_cap": 75, "resolvers": ["1.1.1.1", "1.0.0.1"] , "nics": [   {     "nic_tag": "admin",    "ips": ["YOURIP/PREFIX"],    "gateways": ["YOURGW"]   } ],
    "internal_metadata": {
        "docker:cmd": "[\"/init\"]",
        "docker:env": "[\"HTTPS=ON\", \"HTTPS_PORT=443\", \"HTTP_PORT=80\", \"APP_ENV=prod\", \"MODE=free\"]"
    }
}

Create the zone:

vmadm create -f mailserver.json	

Note that there are some keys in the internal_metadata object that are used by dockerinit and correspond to the environment variable settings and run command specified in an image's Dockerfile and overridden on the docker command-line.

Unlike docker containers, data storage in LX zones is persistent. That means that it's not strictly necessary to mount data storage locations using the docker "volume" commands. However, in order to make upgrades easier, we created the zone with a delegated dataset. When we use the vmadm reprovision command, the main filesystem is replaced with the new image, but any data stored in the delegated dataset is kept. So, we can symlink or lofi-mount all of the data storage locations in the runnng system to locations in the delegated dataset as needed. Note that this whole plan is slightly complicated by the fact that dockerinit doesn't handle mounting the delegated dataset. So, we will create a script that does both of these things and drop it into the appropriate location so that this all happens early in the startup process.

 The poste.io docker container uses s6 as its init system, so the following script is compatible with the way that s6 works. If you're using sysvinit or something else, you will need to modify it accordingly. You'll want to have this run as early as possible so that the storage locations are set up before anything that depends on storing data in one of those locations actually starts.

Copy the following file to /zone/ZONEID/root/etc/cont-init.d/01-init-zfs.sh:

#!/usr/bin/env bash
##!/usr/bin/with-contenv bash
DELEGATED_DATASET=`/native/sbin/zfs list | cut -f 1 -d ' ' | grep "^zones/[0-9a-f-]*/data\$"`
DATASET_MOUNTPOINT=/data
if [ -n $DELEGATED_DATASET ] ; then
echo setting mountpoint of dataset to $DATASET_MOUNTPOINT
	
/native/sbin/zfs set mountpoint=$DATASET_MOUNTPOINT $DELEGATED_DATASET
echo mounting zfs datasets.
/native/sbin/zfs mount -va
  echo "mounting /data/log to /var/log via lofs"
  if [ ! -d $DATASET_MOUNTPOINT/log/pre-lofs ] ; then
    mkdir -p $DATASET_MOUNTPOINT/log/pre-lofs
  fi
  cp -rf /var/log/* /data/log/pre-lofs
  /native/sbin/mount -F lofs -orw $DATASET_MOUNTPOINT/log /var/log
fi

Also, comment out the first set of lines that deal with /var/log and /data/log in 02-directories.sh

Smtp server configuration

Edit the following 2 files:

/opt/haraka-smtp/config/smtp.ini

Change listen to the following:

	listen=0.0.0.0:25,[::0]:25

/opt/haraka-submission/config/smtp.ini

Change listen to the following:

	listen=0.0.0.0:587,0.0.0.0:465,[::0]:587,[::0]:465

 

p0f

p0f is used to fingerprint connections from the SMTP server. Unfortunately the debian version of p0f uses ETHTOOL ioctls to figure out things like link speed. This isn't supported and that causes the SMTP server to hang up on connections. Fortunately, we can use a native p0f and insert it into the zone. The magic of LX is that it knows how to run not only Linux binaries, but also native illumos binaries as well. There's a whole tree of native stuff inside /native that can be used (and indeed must be used if you want to do things like fiddle with the ipf firewall). pkgsrc has p0f but it's an older version that doesn't work the way poste.io expects. No problem-o...

We just get the latest version and compile it in a native zone:

git clone https://github.com/p0f/p0f
pkgin -y in build-essential libpcap	

there's a script in there called build.sh, but it needs some tweaks... $OSTYPE is solaris2.11, so we need to change the spot where it looks for plain "solaris" and fix that. Also, we need to add "-m64" to the base CFLAGS definition. After that, run build.sh and you should have a working native p0f.

in your poste.io zone, create a directory to hold p0f and the native pcap libs... it can be anywhere, but inside /data makes sense:

mkdir -p /data/native_p0f

copy your native p0f and /opt/local/lib/libpcap* there as well. You'll get some extra files like static libs but I didn't bother to skip over them.

mv /usr/sbin/p0f out of the way and in its place, add the following:

#!/bin/sh
LD_LIBRARY_PATH=/data/native_p0f
export LD_LIBRARY_PATH
exec /data/native_p0f/p0f -f /etc/p0f/p0f.fp "$@"	

make sure to set to be executable and things should "magically" start working.

ipf

We could simply use SmartOS' firewall functionality via vmadm, but I already had a standard ruleset, so here's how you employ that (again, using s6's script pattern)

copy /etc/protocols to zone (otherwise ipf may behave strangely.)

create  /etc/cont-init.d/06-ipf.sh:

#!/usr/bin/with-contenv bash
	 
echo "Setting up IPF"
if [[ -f /etc/ipf/ipf.conf ]]; then
echo "Enabling IPF rules for IPv4"
/native/usr/sbin/ipf -E -Fa -f /etc/ipf/ipf.conf
fi
if [[ -f /etc/ipf/ipf6.conf ]]; then
echo "Enabling IPF rules for IPv6"
/native/usr/sbin/ipf -E -6 -f /etc/ipf/ipf6.conf
fi
 

/etc/ipf/ipf.conf:

block in all with frag

pass out quick on eth0 proto tcp from eth0/32 to any keep state
pass out quick on eth0 proto udp from eth0/32 to any keep state
pass out quick on eth0 proto icmp from eth0/32 to any keep state

block in on eth0 all
block in quick on eth0 from 192.168.0.0/16  
#RFC 1918 private IPto  any
block in quick on eth0 from 172.16.0.0/12  #RFC 1918 private IPto  any 
block in quick on eth0 from 10.0.0.0 #RFC 1918 private IP0/ 8  to  any
block in quick on eth0 from 127.0.0.0/8 #loopback8  to  any 
block in quick on eth0 from 0.0.0.0/8 #loopback0/ 8  to  any 
block in quick on eth0 from 169.254.0.0/16  #DHCP auto-configto  any
block in quick on eth0 from 192.0.2.0/24 #reserved for docs24  to  any
block in quick on eth0 from 204.152.64.0/23 to  any #Sun cluster interconnect 
block in quick on eth0 from 224.0.0.0/3 to any #Class D & E multicast
	 
# Block fragments and too short tcp packets
block in quick on eth0 all with frags
block in quick on eth0 proto tcp all with short

# block source routed packets
block in quick on eth0 all with opt lsrr
block in quick on eth0 all with opt ssrr

# Block OS fingerprint attempts and log first occurrence
block in log first quick on eth0 proto tcp from any to any flags FUP
# Block anything with special options
block in quick on eth0 all with ipopts 
# Block public pings and ident
#block in quick on eth0 proto icmp all icmp-type 8
block in quick on eth0 proto tcp from any to any port = 113
pass in quick on eth0 proto icmp from any to any 
pass in quick on eth0 proto tcp from any to any port = 80
pass in quick on eth0 proto tcp from any to any port = 443
pass in quick on eth0 proto tcp from any to any port = 25
pass in quick on eth0 proto tcp from any to any port = 465
pass in quick on eth0 proto tcp from any to any port = 587
pass in quick on eth0 proto tcp from any to any port = 143
pass in quick on eth0 proto tcp from any to any port = 4190

 

/etc/ipf/ipf6.conf:

pass out from any to any keep state
pass in quick proto tcp from any to any port=80
pass in quick proto tcp from any to any port=443
pass in quick proto tcp from any to any port=25
pass in quick proto tcp from any to any port=465
pass in quick proto tcp from any to any port=587
pass in quick proto tcp from any to any port=143
pass in quick proto tcp from any to any port=4190

pass in quick proto icmp from any to any
pass out quick proto icmp from any to any
pass in quick proto ipv6-icmp from any to any
pass out quick proto ipv6-icmp from any to any

block in from any to any	


Migrating mailboxes

If possible, use dsync.

To migrate mailboxes to poste.io, you can do it one at a time (I had email folders in a directory structure and the standard dovecot mechanism didn't like that in combination with poste.io's maildir structure, so I did it one at a time, moving things into the root folder.

doveadm -o imapc_user=username -o imapc_password=passwd-o imapc_host=hostname -o imapc_ssl=imaps -o imapc_port=993 -o imapc_ssl_verify=no -o ssl_client_ca_dir=/etc/ssl -v backup  -R -D -u william@welliver.org  -m n imapc:

 

Upgrading

Backup the following items:

/data

/etc/ipf

/etc/cont-init.d/06-ipf.sh

/etc/protocols

/usr/sbin/p0f

Actually, most of these can be stored in /data/_override and will be automatically put back in on restarts.


Sending mail from postfix servers to poste.io

set up an account that can be used as an authenticated user (but all mail is redirected somewhere else).

pkgsrc cyrus-sasl doesn't include any plugins. The plugins are available, but you'll never find them because they're not named cyrus-sasl-whatever. pkgin av |grep cy2 will list them and then you can install what you need... probably cy2-plugin-login and -plain... Dumb, dumb, dumb.

install mozilla-rootcerts-openssl

postfix changes:

	default_database_type = hash
	relayhost = [smtp.yourdomain]:587
	smtp_sasl_auth_enable = yes
	smtp_sasl_password_maps = hash:/opt/local/etc/postfix/relay_passwd
	smtp_sasl_security_options = noanonymous, noplaintext
	smtp_sasl_tls_security_options = noanonymous
	smtp_sasl_type = cyrus
	smtp_tls_CApath = /opt/local/etc/openssl/certs
	#optional debugging
	smtp_tls_loglevel = 2
	smtp_tls_security_level = encrypt
	smtp_use_tls = yes

 

create /opt/local/etc/postfix/relay_passwd:

[smtp.yourdomain]:587 user:password

 

postmap /opt/local/etc/postfix/relay_passwd

postfix reload

Not categorized | RSS Feed | BackLinks

comments powered by Disqus